#pragma once
#include"Common.hpp"

//这是个类。网络地址和主机地址之间进行转换的类
class InetAddr
{
public: 
    InetAddr(){};    //无参构造



    //传入网络地址   就能转化成为本地地址，想要获取完全可以获取
    InetAddr(struct sockaddr_in &addr)   //收到的网络信息转换成为本主机的序列
        :_addr(addr)
    {   
    //网络转主机  网络序列转主机
        _port = ntohs(_addr.sin_port);    //从网络中拿到的网络序列(端口号)
        // _ip = inet_ntoa(_addr.sin_addr);   //4字节网络风格的IP --> 点分十进制的字符串风格IP

        char ipbuffer[64];
    //这样调用  就可以把四字节风格ip转成字符串风格ip
        inet_ntop(AF_INET,&_addr.sin_addr,ipbuffer,sizeof(_addr));   //长度是结构体对应的长度   不是ipbuffer长度 
        _ip = ipbuffer;
    }
    //上面的是  传网络地址，转主机地址



    //不跟上面一样：上面传入网络地址，这个是以本机地址构造
    //传主机地址，转网络地址     完整ip端口转成为地址
    //主机 转 网络(要注意加上const  不然UdpServer中的0编译不过)
    InetAddr(const std::string &ip,uint16_t port):_ip(ip),_port(port)    //传ip传端口，默认缺省构造
    {
    //主机转网络
        memset(&_addr,0,sizeof(_addr));   //清空内存
        _addr.sin_family = AF_INET;

        inet_pton(AF_INET,_ip.c_str(),&_addr.sin_addr);   //以独立的参数的形式以 AF_INET 形式转化成4字节ip
        //效果等同于
        //local.sin_addr.s_addr = inet_addr(_ip.c_str());
        
        //主机序列转为网络序列
        _addr.sin_port = htons(_port);
    }


    //只有端口号的
    InetAddr(uint16_t port):_port(port),_ip("0")
    {
        //主机转网络
        memset(&_addr,0,sizeof(_addr));
        _addr.sin_family = AF_INET;
        _addr.sin_addr.s_addr = INADDR_ANY;
        _addr.sin_port = htons(_port);
    }


    uint16_t Port()
    {
        return _port;
    }

    std::string Ip() 
    {
        return _ip;
    }

//返回网络地址的接口（注意：对于sendto的第五个参数是 const struct sockaddr*  的指针变量   所以不能返回临时变量）
    const struct sockaddr_in &NetAddr() 
    {
        return _addr;
    }


//* 获取地址
    const struct sockaddr *NetAddrPtr()
    {
        return CONV(_addr);
    }

//* 获取长度
    socklen_t NetAddrLen()
    {
        return sizeof(_addr);
    }

//判断两个地址是否相等(IP地址和端口号完全一样的  才判断是完全一样的)
    bool operator==(const InetAddr &addr)
    {
        return addr._ip == _ip && addr._port == _port;
    }

    std::string StringAddr()
    {
        return _ip + ":" + std::to_string(_port);   //返回 ip+端口号   转换成为字符串 
    }

    ~InetAddr()
    {

    }


private:
    struct sockaddr_in _addr;
    std::string _ip;
    uint16_t _port;
};